# import captcha as captcha
# from django.shortcuts import render
from django.contrib.auth.hashers import check_password
from django.db.models import Q
#redirect用来重定向跳转
from django.shortcuts import redirect
from rest_framework.response import Response
from rest_framework.throttling import AnonRateThrottle
from rest_framework.views import APIView
from .sers import *
from django.http.response import HttpResponse
from .utils import *
from captcha.image import ImageCaptcha
from io import BytesIO  #导入二进制流
import redis#导入redis用来存储获取到的code(随机数)
import datetime

#连接redis
r = redis.Redis(host="localhost", port="6379",decode_responses=True)

# Create your views here.
#验证用户名是否被使用
class UniqueUserView(APIView):
    def post(self,request):
        #1.获取传递来的用户名
        username = request.data.get('username')
        #2.从数据库查询
        queryset = UserProfile.objects.filter(username=username)
        #3.验证用户名是否存在
        if queryset:
            return Response({'msg':'用户名已存在'},status=400)
        #4.返回
        return Response({'msg':'用户名可用'})

#注册用户
class RegisterView(APIView):
    def post(self,request):
        # 获取 短信验证码
        sms_code = request.data.get("sms_code")
        phone = request.data.get("phone")
        sms_code_save = r.get(phone)
        print(sms_code_save)
        if not sms_code_save:
            return Response({"msg": "手机验证码过期", "code": 400})
        if sms_code_save != sms_code:
            return Response({"msg": "手机验证码错误", "code": 400})


        #获取传递来的图片验证码
        img_code = request.data.get('img_code')
        #获取传递来的key
        key = request.GET.get('key')
        #redis取出保存的code(随机数)
        code = r.get(key)
        #验证code
        if not code:
            return Response({'msg':'图片验证码过期','code':400})
        if code != img_code:
            return Response({'msg':'图片验证码错误','code':400})

        #1.创建一个序列化类
        ser = UserSer(data=request.data)
        #2.验证数据
        if ser.is_valid():
            #3.保存
            ser.save()
            return Response({'msg':'注册成功'},status=200)
        #4.返回
        return Response({'msg':'注册失败'},status=400)

def make_img_code(request):
    #1.先生成一个验证码
    code = CodeUtils.make_code_n(4)
    #存储验证码到某个地方,获取前端传来的uuid
    key = request.GET.get('key')
    r.set(key,code,60)
    #2.生成一张图片对象
    image_captche = ImageCaptcha()
    image = image_captche.generate_image(code)
    #创建一个字节流
    bytes_io = BytesIO()
    #把对象存入字节流兑现
    image.save(bytes_io,'jpeg')
    return HttpResponse(bytes_io.getvalue(),content_type="image/jpeg")

#开发 调用短信的接口
from ronglian_sms_sdk import SmsSDK
from django_md.settings import ACCOUNT_SID,AUTH_TOKEN,APP_ID,SECRET_KEY

#限制频繁操作
class MySmRateThorttlo(AnonRateThrottle):
    rate='1/minute'
#发送短信验证码
class SMScodeView(APIView):
    throttle_classes = [MySmRateThorttlo]

    def post(self,request):
        phone=request.data.get('phone')
        code =CodeUtils.make_code_n(4)
        # 保存到我们的redis中
        r.set(phone,code,10*60)
        sdk=SmsSDK(ACCOUNT_SID,AUTH_TOKEN,APP_ID)
        # 发送
        sdk.sendMessage(1,phone,(code,2))
        return Response('验证码已发送请查收')


#登录
from django.contrib.auth import authenticate
#django自带解密码
import jwt
from django.contrib.auth.backends import ModelBackend

class MyModelBackend(ModelBackend):

    def authenticate(self, request, username=None, password=None, **kwargs):
        user = UserProfile.objects.filter(Q(username=username) | Q(phone=username)).first()
        if user and user.check_password(password):
            return user
        else:
            return None

class LoginView(APIView):
    def post(self,request):

        #验证数据 返回查询到的用户信息
        # user = authenticate(**request.data)
        username = request.data.get('username')
        password = request.data.get('password')
        user = UserProfile.objects.filter(Q(username=username)|Q(phone=username)).first()
        if user and user.check_password(password):
            payload = {
                'uid':user.id,
                'exp':datetime.datetime.utcnow()+datetime.timedelta(hours=24)
            }
            token = jwt.encode(payload,SECRET_KEY)
            return Response({'msg':'登录成功','token':token,'code':200,'username':user.username})
        return Response({'msg':'登录失败','code':400})

#开发一个获取微博认证页接口
from django_md.settings import WEIBO_App_Key,WEIBO_URL,WEIBO_App_Secret
#导入第三方库
import requests
#步骤一
class WeiboUrlView(APIView):
    def get(self,request):
        weibo_url = "https://api.weibo.com/oauth2/authorize?client_id={}&redirect_uri={}".format(WEIBO_App_Key,WEIBO_URL)
        #获取认证页必要两个微博接口参数client_id  redirect_uri

        return Response({'url':weibo_url})

    #步骤三
    def post(self, request):
        #  获取到code，然后 去 访问token
        code = request.data.get("code")
        #使用获取token值的接口必须拥有的5个参数(通过导包requests连接第三方库)
        r = requests.post("https://api.weibo.com/oauth2/access_token", {
            "client_id": WEIBO_App_Key,
            "client_secret": WEIBO_App_Secret,
            "grant_type": "authorization_code",
            "code": code,
            "redirect_uri": WEIBO_URL
        })

        # 获取 返回的对象(获取token和uid)
        print(r.json())
        access_token = r.json()["access_token"]
        uid = r.json()["uid"]

        #进行第三方用户注册操作
        #首先判断用户有没有登录过，登录过，则不注册，如果没有登录过，则注册用户
        openUser = OpenUser.objects.filter(uid="wb" + uid).first()
        if not openUser or not openUser.user:
            # 不存在，则注册
            openUser = OpenUser.objects.create(uid="wb" + uid, type="微博")
            return Response({"msg": "还没有绑定本地账号", "uid": openUser.uid, "code": 400})
        else:
            # 有这个月的三方账号，且已经绑定成功, 需要返回令牌
            # 判断
            user = openUser.user
            if user:
                payload = {
                    "uid": user.id,
                    'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=2),
                }
                token = jwt.encode(payload, SECRET_KEY)
                return Response({"msg": "登录成功", "token": token, "code": 200, "username": user.username})

#步骤二
def weibo_callback(request):
    #获取在微博第三方页面的code
    code = request.GET.get("code")
    return redirect("http://127.0.0.1:8080/#/oauth?code="+code)



# 三方账号 绑定 本地账号接口
class BindUserView(APIView):

    def post(self, request):
        # 绑定用户
        phone = request.data.get("phone")
        password = request.data.get("password")

        uid = request.data.get("uid")

        # 先去 数据库查询  是否存在该手机号
        user = UserProfile.objects.filter(phone=phone).first()

        # 查找到 三方账号
        open_user = OpenUser.objects.filter(uid=uid).first()
        if user:
            if not user.check_password(password):
                # 密码输入错误
                return Response({"msg": "密码输入错误，绑定失败"})
        else:
            # 该手机号 没有被使用过
            # 创建一个新的 本地账号
            user = UserProfile.objects.create_user(username="md" + phone, password=password, phone=phone)
        # 绑定 三方账号 到本地账号
        open_user.user = user
        open_user.save()
        return Response({"msg": "绑定成功"})
